package com.cskaoyan.javase.oop2._0encapsulate._0introduction;

/**
 * 封装（encapsulate）是指将数据及相关操作绑定在一起的一种编程机制，使其构成一个不可分割的独立实体。
 *
 * 在Java中，类就是这样一种结构。
 * 当然，数据被保护在类的内部，是为了尽可能地隐藏内部的细节，只保留一些对外"接口"使之与外部发生联系。
 * 之所以要封装，是为了将代码的使用者和实现者分开。
 * 使用者能够完全得到自己想要的功能，又不需要思考过多细节；
 * 实现者可以隐藏功能实现的细节，方便灵活进行修改而不影响使用者使用。
 * 以上这些封装的好处,实际上就是访问权限修饰符的实现,Java实现封装一个是靠class封装数据和操作,另外就需要使用访问权限修饰符
 *
 * 从实际的语法角度上来说，Java当中的封装是依赖于访问权限修饰符来实现：
 * 比如完全不需要被外界知道的属性，在类中完全可以私有化。如不希望被外界访问的age属性：
 * private int age;
 *
 * 有些时候，一些属性虽然支持给外界访问，但希望能够控制它的访问时，就需要先私有化它，然后再使用 Getter/Setter 方法。
 * Getter/Setter方法的格式比较固定：
 * Getter方法提供外界访问的途径，一般命名为getXxx（Xxx是成员变量名），一般直接返回成员变量得值即可。
 * 语法:
 *      public 该成员变量的数据类型 getXxx(){
 *          return 成员变量名;
 *      }
 *
 *
 * Setter方法提供外界赋值的途径，一般命名为setXxx（Xxx是成员变量名），一般使用this关键字完成赋值就可以了。
 *  语法:
 *  public void setXxx(数据类型 成员变量名){
 *      this.成员变量名 = 成员变量名;
 *  }
 * 注: 一般来说,方法的形参的数据类型和变量名都和成员变量保持一致.
 *
 * 使用Getter/Setter方法的好处:
 *      1.使用方法后,分离了成员变量的访问和赋值
 *          成员变量的读写分离了
 *      2.使用方法后,就可以控制成员变量的访问
 *          之前是控制不了的
 *          可以控制赋值
 *          也可以控制访问的取值
 *
 * @since 17:31
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        Student s = new Student();
        // s.age
        // System.out.println(s.name);
        // s.name = "李四";
        // System.out.println(s.name);
        // System.out.println(s.getName());
        // s.setName("王八");
        // System.out.println(s.getName());
        //
        // System.out.println(s.getAge());

        s.setAge(120);
        System.out.println(s.getAge());
    }
}

class Student {
    // 私有成员外界访问不到了
    private int age;

    // name希望被外界访问,但是希望能够控制这个访问,咋办呢?
    /*
        仅靠对象名点访问成员变量是不可能控制访问的
        所以应该私有化它,先让外界不可以访问
        然后提供方法,在方法中控制它的访问
     */
    private String name = "张三";

    // 提供name的访问方法,称之为Getter方法
    public String getName() {
        return name;
    }

    // 提供name的赋值方法,称之为Setter方法
    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }


    public void setAge(int age) {
        // 做判断,年龄不合法,不允许赋值
        if (age > 130) {
            System.out.println("你筑基成功了吗?");
            return;
        }
        if (age < 1) {
            System.out.println("你不能活到过去吧?");
            return;
        }
        // 合法年龄 可以赋值
        this.age = age;
    }
}